package com.etime.shycourse.services.coupons.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.etime.shycourse.services.coupons.interfaces.CoursepackageServices;
import com.etime.shycourse.dao.*;
import com.etime.shycourse.dto.CouponrangePackageDto;
import com.etime.shycourse.pojo.Couponrange;
import com.etime.shycourse.pojo.Course;
import com.etime.shycourse.pojo.Coursepackage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import java.util.List;
import java.util.concurrent.atomic.AtomicReference;

/**

 *
 * @author wb
 * @since 2022-03-15
 */
@Service
public class CoursepackageServiceImpl implements CoursepackageServices {
    @Autowired
    private CourseMapper courseMapper;
    // 课程类型 dao
    @Autowired
    private CoursetypeMapper typeMapper;

    @Autowired
    private CoursepackageMapper mapper;
    @Autowired
    private PackageimportcourseMapper packageimportcourseMapper;
    @Autowired
    private CouponrangeMapper couponrangeMapper;

    /**
     * 查询可以用课程
     *
     * @return List<Course>
     */
    @Override
    public List<Course> selectCourseList() {
        QueryWrapper<Course> wrapper = new QueryWrapper<>();
        wrapper.eq("coursestate", 1);
        //课程审核状态（courseaudit） = 1
        wrapper.eq("courseaudit", 1);
     /*   // 根据可用状态 课程父类型id=-1 查询出 课程类型是id
        List<Coursetype> courseTypeList = typeMapper.selectList(new QueryWrapper<Coursetype>().select("coursetypeid").eq("coursetypestate", 1));
        // courseTypeIdList 可用课程类型id的集合
        ArrayList<Integer> courseTypeIdList = new ArrayList<> ();
        courseTypeList.forEach ((l) -> {
            courseTypeIdList.add (l.getCoursetypeid ());
        });
        // 用户搜索 没有 课程类型id  就只查找课程类型可用状态的
        wrapper.and (w -> {
            // SQL语句中in的个数限制为1000
            w.in ("coursetypeid", courseTypeIdList); // 为了保证课程大的类型可用
        });*/
        //查询的字段 课程id 课程名 课程图片
        wrapper.select ("courseid", "coursetitle", "coursepic");
        //3、排序：按照课程排序（coursesort）降序排列
        wrapper.orderByDesc ("coursesort");
        return courseMapper.selectList (wrapper);
    }


    @Override
    public List<Coursepackage> selectCoursePackageList() {
        // 1--可用
        // 0--不可用
        return mapper.selectList (new QueryWrapper<Coursepackage> ().eq ("packagestate", 1));
    }

    /**
     * 课程兑换劵, 创建 优惠券使用范围.
     * 第一步 创建 课程包
     * 第二步 创建 课程包包含课程
     * 第三步 创建 优惠券使用范围
     *
     * @return integer 0 创建失败
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public Integer insertCouponRangePackage(CouponrangePackageDto packageDto) {
        if (packageDto != null) {
            try {
                // 第一步 创建 课程包
                Integer packageId = this.insertPackage(packageDto);
                // 返回的课程包id
                if (packageId == 0) {
                    return 0;
                    //创建失败
                }
                // 第二步 创建 课程包包含课程
                if (packageDto.getPackageimportcourse().size() > 0) {
                    Integer integer = this.insertPackageimportcourse(packageDto, packageId);
                } else {
                    // 课程包为空创建失败
                    return 0;
                }
                // 第三步 创建 优惠券使用范围
                packageDto.setCourseorpackage(2);
                //1---关联课程 2--关联课程包
                packageDto.setRangpackageid(packageId);
                //设置优惠劵课程包id
                int insert = couponrangeMapper.insert((Couponrange) packageDto);
                if (insert == 0) {
                    try {
                        throw new Exception("创建课程包失败！");
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            } catch (Exception e) {
                e.printStackTrace ();
                // @Transactional和try catch捕获异常会让注解失效
                TransactionAspectSupport.currentTransactionStatus ().setRollbackOnly ();
                return 0;
            }
            return 1;
        }
        return 0;
    }

    /**
     * 创建课程包
     *
     * @param
     * @return 失败返回0 成功返回1
     */
    @Override
    public Integer insertPackage(Coursepackage coursepackage) {
        // 创建课程包
        coursepackage.setPackagestate(1);
        return mapper.insert(coursepackage);
    }

    @Override
    public Integer updatePackageById(Coursepackage coursepackage) {
        return mapper.updateById (coursepackage);
    }

    /**
     * 查询课程包
     *
     * @param packageId
     * @return Coursepackage
     */
    @Override
    public Coursepackage selectCoursePackageById(Integer packageId) {
        return mapper.selectById (packageId);
    }

    /**
     * 课程包分页
     *
     * @return Page<Coursepackage>
     */
    @Override
    public Page<Coursepackage> selectCoursePackagePage(Long pageNum, Long pageSize) {
        QueryWrapper<Coursepackage> wrapper = new QueryWrapper<> ();
        wrapper.orderByDesc ("packageid");
        Page<Coursepackage> page;
        if (pageNum != null & pageSize != null) {
            page = new Page<> (pageNum, pageSize);
        } else {
            page = new Page<> ();
        }
        return mapper.selectPage (page, wrapper);
    }

    /**
     * 创建课程包
     * 成功返回课程包id
     *
     * @param packageDto
     * @return 失败返回0
     */
    private Integer insertPackage(CouponrangePackageDto packageDto) {
        // 创建课程包
        Coursepackage coursepackage = new Coursepackage ();
        // 课程包名称
        coursepackage.setPackagename (packageDto.getPackagename ());
        // 课程包说明
        coursepackage.setPackagedesc (packageDto.getPackagedesc ());
        // 课程包状态 1--可用 0--不可用
        // 默认 1 可用
        coursepackage.setPackagestate (1);
        return mapper.insert (coursepackage) > 0 ? coursepackage.getPackageid () : 0;
    }

    /**
     * 创建 课程包包含课程
     *
     * @param packageDto
     * @return 失败返回0
     */
    Integer insertPackageimportcourse(CouponrangePackageDto packageDto, Integer packageId) {
        /*
        Atomic家族主要是保证多线程环境下的原子性，
        相比synchronized而言更加轻量级。比较常用的是AtomicInteger，
        作用是对Integer类型操作的封装，
        而AtomicReference作用是对普通对象的封装。
        */
        AtomicReference<Integer> insert = new AtomicReference<> (0);
        packageDto.getPackageimportcourse ().forEach (p -> {
            p.setPackageid (packageId);//设置课程包id
            insert.set (packageimportcourseMapper.insert (p));
            if (insert.get () == 0) {
                try {
                    throw new Exception ("创建课程包失败！");
                } catch (Exception e) {
                    e.printStackTrace ();
                }
            }

        });
        return insert.get ();
    }

}
